package org.example.demo.service;

import org.example.demo.dto.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

@Service
public class CacheService {


    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 关于@Cacheable
     * 使用该注解的方法当缓存存在时，会从缓存中获取数据而不执行方法，当缓存不存在时，会执行方法并把返回结果存入缓存中。一般使用在查询方法上，可以设置如下属性：
     *
     * value：缓存名称（必填），指定缓存的命名空间；
     * key：用于设置在命名空间中的缓存key值，可以使用SpEL表达式定义；
     * unless：条件符合则不缓存；
     * condition：条件符合则缓存。
     */
    @Cacheable(cacheNames = "cacheString", key = "#key")
    public String cacheStringValue(String key) {
        System.out.println("get data");
        return key + "test";
    }

    @Cacheable(cacheNames = "cacheLocalDateTime", key = "#key")
    public LocalDateTime cacheLocalDateTimeValue(String key) {
        System.out.println("get data");
        return LocalDateTime.now();
    }


    @Cacheable(cacheNames = "cacheUser", key = "#key")
    public User cacheObjectValue(String key) {
        System.out.println("get data");
        return new User("kevin", 18);
    }


    @Cacheable(cacheNames = "cacheUser", key = "#key", condition = "#key!='key-user'")
    public User cacheObjectValueCondition(String key) {
        System.out.println("get data");
        return new User("kevin", 18);
    }

    @Cacheable(cacheNames = "cacheUser", key = "#key", unless = "#result.age==18")
    public User cacheObjectValueUnless(String key) {
        System.out.println("get data");
        return new User("kevin", 18);
    }


    @Cacheable(cacheNames = "cacheNull", key = "#key")
    public User cacheNullValue(String key) {
        System.out.println("get data");
        return null;
    }


    @Cacheable(cacheNames = "cacheNull")
    public String cacheValue() {
        System.out.println("get data");
        return "test-value";
    }


    @CachePut(cacheNames = "cacheUser", key = "#key")
    public User cachePutObjectValue(String key) {
        System.out.println("get data");
        return new User("kevin", 18);
    }

    @CacheEvict(cacheNames = "cacheUser", key = "#key")
    public void deleteUser(String key) {
        System.out.println("delete data");
        System.out.println(redisTemplate.opsForValue().get("cacheUser::test-user"));
    }

    @CacheEvict(cacheNames = "cacheUser", key = "#key", beforeInvocation = true)
    public void deleteUser2(String key) {
        System.out.println("delete data");
        System.out.println(redisTemplate.opsForValue().get("cacheUser::test-user"));
    }


}
